iT邦幫忙

2026 iThome 鐵人賽

DAY 23
0
Security

那些留在電腦裡的證據:從零開始認識數位鑑識系列 第 23 篇

[DAY 23] 刪掉的檔案真的救得回來?實作 Run List 還原

  • 分享至 

  • xImage
  •  

前一篇已經看過 Run List 裡的 Length、Relative Offset、LCN 和 Byte Offset 要怎麼算,這篇就直接把這些結果拿來實際還原檔案。

這次使用的 Disk Image 是 HL-WS03.001,目標是找回其中被刪除的 manifest_0512.png。

整個流程會先在 $MFT 中找到 manifest_0512.png 對應的 MFT Record,再從這筆 Record 的 $DATA Attribute 找出 Run List,最後把分散在 Image 不同位置的資料重新拼回來。

找到 manifest_0512.png 的 MFT Record

先用 HxD 開啟 HL-WS03.001,搜尋 FILE0。

搜尋後會找到很多結果,這些結果每一筆相差 1024 Bytes,也就是一筆一筆的 MFT Record。

https://ithelp.ithome.com.tw/upload/images/20261007/20146591L9mDTlxrwj.png

逐筆查看內容,在 Offset 78848 的 Record 中,可以從右側的文字區看到 manifest_0512.png。

https://ithelp.ithome.com.tw/upload/images/20261007/20146591T219GdgNVe.png

因此可以確認這一筆就是目標檔案所對應的 MFT Record。

找到正確的 MFT Record 後,接著就在這筆 Record 裡尋找 $DATA Attribute。

$DATA 的 Type ID 是 80 00 00 00。

在 Offset 79128 可以看到 80 00 00 00 ,也就是 $DATA Attribute 的實際起始位置 ($DATA Attribute Offset)。

https://ithelp.ithome.com.tw/upload/images/20261007/201465913mVC1avKGh.png

在 $DATA Attribute 開頭往後 8 Bytes 的位置,可以看到 Non-resident Flag 為 01。

代表這個檔案的內容不是直接存放在 MFT Record 裡,而是記錄在其他 Cluster 中,因此接下來需要透過 Run List 找到真正的資料位置。

Run List 的起始位置會記錄在 $DATA Header 中,而這個 Offset 就位在 $DATA Attribute 開頭往後 32 Bytes 的位置。

這筆 $DATA 的起點是 79128,所以:

79,128 + 32
= 79,160

從這個位置可以看到 40 00,以 Little-endian 轉換後為 64 Bytes,表示 Run List 位在 $DATA Attribute 開頭往後 64 Bytes 的位置。

因此:

79,128 + 64
= 79,192

跳到 Offset 79192,可以找到:

21 13 5A 48 22 16 00 CF EC 21 0D 56 14 00

https://ithelp.ithome.com.tw/upload/images/20261007/20146591ETumxBz2Vv.png

這就是 manifest_0512.png 的 Run List。

按照 DAY 22 介紹的方式解開後,可以得到:

Run Length Relative Offset LCN Byte Offset
Run 1 19 Clusters Start 18,522 75,866,112
Run 2 22 Clusters -4,913 13,609 55,742,464
Run 3 13 Clusters +5,206 18,815 77,066,240

有了 Byte Offset,就知道三段 File Data 分別位在 Disk Image 的哪個位置。

把三個 Run 從 Image 裡取出

這個 Volume 的 Cluster Size 是 4096 Bytes,因此還要根據每個 Run 的 Length 算出實際需要取出的資料大小。

Run 1 有 19 Clusters:

19 × 4,096
= 77,824 Bytes

Run 1 的起始位置是 75,866,112,因此結束位置為:

75,866,112 + 77,824 - 1
= 75,943,935

Run 2 有 22 Clusters:

22 × 4,096
= 90,112 Bytes

Run 3 有 13 Clusters:

13 × 4,096
= 53,248 Bytes

整理後:

Run Start Offset Length End Offset
Run 1 75,866,112 77,824 Bytes 75,943,935
Run 2 55,742,464 90,112 Bytes 55,832,575
Run 3 77,066,240 53,248 Bytes 77,119,487

接著就可以在 HxD 裡把三段資料分別取出。

先按 Ctrl + G 跳到 Run 1 的起始位置 75866112。

再使用 Ctrl + E 選取 77824 Bytes。

https://ithelp.ithome.com.tw/upload/images/20261007/20146591ABb5LZxUMz.png

將 Run 1 的資料複製起來,新增檔案 manifest_0512.bin 並貼上。

https://ithelp.ithome.com.tw/upload/images/20261007/201465912x5wJ4ESl2.png

接著用相同的方法取出 Run 2 和 Run 3,並依序接在 manifest_0512.bin 的尾端。

Run 2
Start Offset:55742464
Length:90112 Bytes
Run 3
Start Offset:77066240
Length:53248 Bytes

三個 Run 總共有:

19 + 22 + 13
= 54 Clusters

因此拼接後的大小為:

54 × 4,096
= 221,184 Bytes

不過,這個 221,184 Bytes 是檔案配置到的空間大小,還不一定等於檔案真正的內容大小。

Trim 到真正的 File Size

回到原本的 $DATA Attribute,可以從 Header 裡確認這個檔案的 Allocated Size 和 Logical Size。

在 Non-resident $DATA 中,從 Attribute 開頭往後 40 Bytes 的位置記錄的是 Allocated Size。

00 60 03 00 00 00 00 00

以 Little-endian 轉換後為:

0x36000 = 221,184 Bytes

而從 $DATA Attribute 開頭往後 48 Bytes 的位置,記錄的是 Logical Size。

7C 57 03 00 00 00 00 00

以 Little-endian 轉換後為:

0x3577C = 219,004 Bytes

因此,這個檔案的 Allocated Size 是 221,184 Bytes,但真正的 Logical Size 只有 219,004 Bytes,兩者相差 2,180 Bytes。

也就是說,三個 Run 雖然總共配置了 221,184 Bytes 的空間,但真正屬於檔案內容的只有前 219,004 Bytes,最後多出的 2,180 Bytes 並不屬於原始檔案內容。

因此,拼接完成的 manifest_0512.bin 還需要進一步 Trim。在 HxD 中,從 Decimal Offset 219004 開始選取到檔案結尾並刪除,只保留前 219,004 Bytes,就能得到正確的檔案大小。

https://ithelp.ithome.com.tw/upload/images/20261007/20146591lhIUAeB5l3.png

Trim 完成後,再將檔案重新命名成 manifest_0512.png 並開啟,就可以看到成功還原的 Shipping Manifest。

https://ithelp.ithome.com.tw/upload/images/20261007/20146591xIQNgGGGif.png


上一篇
[DAY 22] Run List 怎麼算?從 Hex 推回檔案的位置
下一篇
[DAY 24] 當證據開始「說謊」:認識 Anti-Forensics
系列文
那些留在電腦裡的證據:從零開始認識數位鑑識 共 24 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言